home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / vgl20.zip / VGLGIF.C < prev    next >
C/C++ Source or Header  |  1993-05-14  |  5KB  |  210 lines

  1. /*****************************************************************************
  2.  VGLGIF.C
  3.  
  4.  vglGif( char* file, char far* buffer, char far* palette,
  5.          int* width, int* height );
  6.  
  7.  Routine to load a 256 color .GIF file into a memory buffer.  *Only* 256
  8.  color images are supported here!  Sorry, no routines to SAVE .GIFs...
  9.  Memory required is allocated on the fly and no checks are in place.  If you
  10.  don't have enough memory it will likely crash.  It's easy to add the checks
  11.  yourself, just put one after each call to malloc().  If you supply a pointer
  12.  to a palette, it will be filled in.  If you supply a pointer to a width
  13.  and/or height variable, it will be filled in as well.
  14.  
  15.  Mark Morley
  16.  morley@camosun.bc.ca
  17. *****************************************************************************/
  18.  
  19. #include <stdio.h>
  20.  
  21. #define MAX_CODES     4096
  22.  
  23. static FILE*          fp;
  24. static int            curr_size;
  25. static int            clear;
  26. static int            ending;
  27. static int            newcodes;
  28. static int            top_slot;
  29. static int            slot;
  30. static int            navail_bytes = 0;
  31. static int            nbits_left = 0;
  32. static unsigned char  b1;
  33. static unsigned char  byte_buff[257];
  34. static unsigned char* pbytes;
  35. static unsigned char* stack;
  36. static unsigned char* suffix;
  37. static unsigned int*  prefix;
  38.  
  39. static unsigned long code_mask[13] =
  40. {
  41.    0L,
  42.    0x0001L, 0x0003L,
  43.    0x0007L, 0x000FL,
  44.    0x001FL, 0x003FL,
  45.    0x007FL, 0x00FFL,
  46.    0x01FFL, 0x03FFL,
  47.    0x07FFL, 0x0FFFL
  48. };
  49.  
  50. static int pascal
  51. get_next_code()
  52. {
  53.    register int  i;
  54.    static unsigned long ret;
  55.  
  56.    if( ! nbits_left )
  57.    {
  58.       if( navail_bytes <= 0 )
  59.       {
  60.      pbytes = byte_buff;
  61.          navail_bytes = getc( fp );
  62.      if( navail_bytes )
  63.         for( i = 0; i < navail_bytes; ++i )
  64.                *(byte_buff + i) = getc( fp );
  65.       }
  66.       b1 = *pbytes++;
  67.       nbits_left = 8;
  68.       --navail_bytes;
  69.    }
  70.    ret = b1 >> (8 - nbits_left);
  71.    while( curr_size > nbits_left )
  72.    {
  73.       if( navail_bytes <= 0 )
  74.       {
  75.      pbytes = byte_buff;
  76.          navail_bytes = getc( fp );
  77.      if( navail_bytes )
  78.         for( i = 0; i < navail_bytes; ++i )
  79.                *(byte_buff + i) = getc( fp );
  80.       }
  81.       b1 = *pbytes++;
  82.       ret |= b1 << nbits_left;
  83.       nbits_left += 8;
  84.       --navail_bytes;
  85.    }
  86.    nbits_left -= curr_size;
  87.  
  88.    return( (int) (ret & *(code_mask + curr_size)) );
  89. }
  90.  
  91. vglGif( char* file, char far* buffer, char far* pal, int* width, int* height )
  92. {
  93.    unsigned char* sp;
  94.    int            code, fc, oc;
  95.    int            i;
  96.    unsigned char  size;
  97.    int            c;
  98.    unsigned char  buf[1028];
  99.    unsigned char  red;
  100.    unsigned char  grn;
  101.    unsigned char  blu;
  102.  
  103.    fp = fopen( file, "rb" );
  104.    if( !fp )
  105.       return( 0 );
  106.    fread( buf, 1, 6, fp );
  107.    if( strncmp( buf, "GIF", 3 ) )
  108.    {
  109.       fclose( fp );
  110.       return( 0 );
  111.    }
  112.    fread( buf, 1, 7, fp );
  113.    for( i = 0; i < 768; )
  114.    {
  115.       red = getc( fp );
  116.       grn = getc( fp );
  117.       blu = getc( fp );
  118.  
  119.       if( pal )
  120.       {
  121.          pal[i++] = red >> 2;
  122.          pal[i++] = grn >> 2;
  123.          pal[i++] = blu >> 2;
  124.       }
  125.       else
  126.          i += 3;
  127.    }
  128.    fread( buf, 1, 5, fp );
  129.    i = getw( fp );
  130.    if( width )
  131.       *width = i;
  132.    i = getw( fp );
  133.    if( height )
  134.       *height = i;
  135.    if( !buffer )
  136.       return( 1 );
  137.    fread( buf, 1, 1, fp );
  138.    size = getc( fp );
  139.    if( size < 2 || 9 < size )
  140.    {
  141.       fclose( fp );
  142.       return( 0 );
  143.    }
  144.  
  145.    stack = (unsigned char*) malloc( MAX_CODES + 1 );
  146.    suffix = (unsigned char*) malloc( MAX_CODES + 1 );
  147.    prefix = (unsigned int*) malloc( sizeof(int) * (MAX_CODES + 1) );
  148.  
  149.    curr_size = size + 1;
  150.    top_slot = 1 << curr_size;
  151.    clear = 1 << size;
  152.    ending = clear + 1;
  153.    slot = newcodes = ending + 1;
  154.    navail_bytes = nbits_left = 0;
  155.    oc = fc = 0;
  156.    sp = stack;
  157.    while( (c = get_next_code()) != ending )
  158.    {
  159.       if( c == clear )
  160.       {
  161.      curr_size = size + 1;
  162.      slot = newcodes;
  163.      top_slot = 1 << curr_size;
  164.      while( (c = get_next_code()) == clear );
  165.      if( c == ending )
  166.         break;
  167.      if( c >= slot )
  168.         c = 0;
  169.      oc = fc = c;
  170.          *buffer++ = c;
  171.       }
  172.       else
  173.       {
  174.      code = c;
  175.      if( code >= slot )
  176.      {
  177.         code = oc;
  178.         *sp++ = fc;
  179.      }
  180.      while( code >= newcodes )
  181.      {
  182.         *sp++ = *(suffix + code);
  183.         code = *(prefix + code);
  184.      }
  185.      *sp++ = code;
  186.      if( slot < top_slot )
  187.      {
  188.         *(suffix + slot) = fc = code;
  189.         *(prefix + slot++) = oc;
  190.         oc = c;
  191.      }
  192.      if( slot >= top_slot && curr_size < 12 )
  193.      {
  194.         top_slot <<= 1;
  195.         ++curr_size;
  196.      }
  197.      while( sp > stack )
  198.      {
  199.         --sp;
  200.             *buffer++ = *sp;
  201.      }
  202.       }
  203.    }
  204.    free( stack );
  205.    free( suffix );
  206.    free( prefix );
  207.    fclose( fp );
  208.    return( 1 );
  209. }
  210.